/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ttc_protocol.c                                     */
/*  NOTE      =                                                    */
/*  DATE      = 2014/09/26 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frlog.h"

#include "conntrack.h"
#include "frct_comm.h"
#include "module.h"

#include "../ora_core.h"
#include "../comm/ora_comm.h"
#include "../comm/ora_util.h"
#include "ora_ttc_proto.h"
#include "ora_mar_engine.h"
#include "ora_tti_pro.h"
#include "ora_tti_dty.h"
#include "ora_tti_oversion.h"
#include "ttc7/ora_ttc7_logon.h"
#include "ttc7/ora_ttc7_oall7.h"
#include "ttc7/ora_ttc7_oopen.h"
#include "ttc7/ora_ttc7_oclose.h"
#include "ttc8/ora_ttc8_rpc.h"
#include "ttc8/ora_ttc8_logon.h"
#include "ttc8/ora_ttc8_oall8.h"
#include "ttc8/ora_ttc8_commoncall.h"
#include "ttc7/ora_ttc7_odscrarr.h"
#include "ttc8/ora_ttc8_tti_lob.h"
#include "../comm/ora_stmt.h"

extern void *g_p_apm_context;


FR_STATIC int __check_sess_params_long_ignored(L7_session *p_st_session
                                                , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_logon(L7_session *p_st_session
                                        , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc7_stmt_req(L7_session *p_st_session
                                                , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
         p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc7_simple(L7_session *p_st_session
                                            , L7session_ora *p_st_sess)
{
    return __check_sess_params_ttc7_stmt_req(p_st_session, p_st_sess);
}

FR_STATIC int __check_sess_params_ttc7_stmt_resp(L7_session *p_st_session
                                                , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc8_stmt_req(L7_session *p_st_session
                                                , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc8_stmt_resp(L7_session *p_st_session
                                                , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc7(L7_session *p_st_session
                                        , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_useCLR_big_chunks == APM_ORA_FLAG_UNSET)
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_oci is unset\n");
        if (p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_special_field is unset\n");
        if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_CHR_conversion_flags is unset\n");
        if (p_st_sess->i_useCLR_big_chunks == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_useCLR_big_chunks is unset\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

FR_STATIC int __check_sess_params_ttc8(L7_session *p_st_session
                                        , L7session_ora *p_st_sess)
{
    if (p_st_session == NULL || p_st_sess == NULL)
        return FR_FAIL;

    if (p_st_sess->i_use_special_field == FR_NO &&
        (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET ||
//        p_st_sess->i_ttc8_stmt_resp_oeraij == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET))
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_oci is unset\n");
        if (p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_special_field is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_i is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_j is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_dml is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_udskpos is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_udsflg is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbkm is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbni1 is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbab2 is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_rpag is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_rpadml is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oereocs is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oerendseq is unset\n");
//        if (p_st_sess->i_ttc8_stmt_resp_oeraij == APM_ORA_FLAG_UNSET)
//            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oeraij is unset\n");
        if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_CHR_conversion_flags is unset\n");
        return FR_FAIL;
    }
    else if (p_st_sess->i_use_special_field == FR_YES &&
        (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ||
//        p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 == APM_ORA_FLAG_UNSET ||
//        p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 == APM_ORA_FLAG_UNSET ||
        p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET))
    {
        ORA_PRINT_EMERG("incomplete sess params for long connection support\n");
        if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_oci is unset\n");
        if (p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_use_special_field is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_i is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_j is unset\n");
        if (p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_req_dml is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_udskpos is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_udsflg is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbkm is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbni1 is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_dcbab2 is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_rpag is unset\n");
//        if (p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET)
//            ORA_PRINT_CRIT("i_ttc8_stmt_resp_rpadml is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oereocs is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oerendseq is unset\n");
        if (p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oci_oerskip8 is unset\n");
//        if (p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 == APM_ORA_FLAG_UNSET)
//            ORA_PRINT_CRIT("i_ttc8_stmt_resp_oci_oerskip6 is unset\n");
        if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
            ORA_PRINT_CRIT("i_CHR_conversion_flags is unset\n");
        return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  分析tti请求
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_tti_fun_analyze_req(Conntrack *p_st_conn
                                        , L7session_ora *p_st_sess
                                        , L7_ora_packet *p_st_ora_packet
                                        , Frhash_header *p_st_hash_report)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    int i_this_func_ret = APM_L7_ANALYZE_SET_REQ(APM_L7_ANALYZE_SUCC);
    short s_fun_code;                                // fun code

    // 获取 func code
    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_fun_code) != FR_SUCC)
        goto error;

    switch (s_fun_code)
    {
        case ORA_FUN_CODE_OPING:
            bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
            break;

        case ORA_FUN_CODE_O3LOGA:           // ttc7 用户登录，发送用户名
            ORA_PRINT_INFO("ttc7 logon, send username\n");
            APM_ORA_SET_PHASE_P_LOG1_REQ(p_st_sess->ull_bits_phase_progress);
            if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_LOG1);
            if (ora_ttc7_logon_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
            break;

        case ORA_FUN_CODE_O3LOGON:          // ttc7 用户登录，发送用户名和密码
            ORA_PRINT_INFO("ttc7 logon, send username and password\n");
            APM_ORA_SET_PHASE_P_LOG2_REQ(p_st_sess->ull_bits_phase_progress);
            if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_LOG2);
            if (ora_ttc7_logon_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
            break;

        case ORA_FUN_CODE_OSESSKEY:         // ttc8 用户登录，发送用户名
            ORA_PRINT_INFO("ttc8 logon, send username\n");
            APM_ORA_SET_PHASE_P_LOG1_REQ(p_st_sess->ull_bits_phase_progress);
            if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OSESSKEY);
            if (ora_ttc8_logon_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
            break;

        case ORA_FUN_CODE_OAUTH:            // ttc8 用户登录，发送用户名和密码
            ORA_PRINT_INFO("ttc8 logon, send username and password\n");
            APM_ORA_SET_PHASE_P_LOG2_REQ(p_st_sess->ull_bits_phase_progress);
            if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OAUTH);
            if (ora_ttc8_logon_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
            break;

        case ORA_FUN_CODE_OALL7:            // ttc7 执行statement请求
            ORA_PRINT_INFO("ttc7 0x0347 stmt request\n");
            if (__check_sess_params_ttc7_stmt_req(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_push_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL7);
            p_st_sess->c_ttc_api_version = 7;
            if (ora_ttc7_oall7_unpack0347_req(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OALL_0303:        // 0x0303
            ORA_PRINT_INFO("0x0303 stmt request\n");
            if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL8);
            p_st_sess->c_ttc_api_version = 8;
            if (ora_ttc8_oall8_unpack0303_req(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OALL8:            // ttc8 执行statement请求
            ORA_PRINT_INFO("ttc8 0x035E stmt request\n");
            if (__check_sess_params_ttc8_stmt_req(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL8);
            p_st_sess->c_ttc_api_version = 8;
            if (ora_ttc8_oall8_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OFETCH:           // 查询时fetch命令
            ORA_PRINT_INFO("0x0305 fetch\n");
            if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            if (p_st_sess->c_ttc_api_version == 7)
                ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL7);
            else if (p_st_sess->c_ttc_api_version == 8 || p_st_sess->i_use_special_field == FR_YES)
                ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL8);
            else
            {
                ORA_PRINT_DBG("Don't know ttc api version.\n");
                goto error;
            }
            if (ora_ttc8_oall8_unpack_fetch_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OOPEN:            // ttc7 执行statement时申请cursor请求
            ORA_PRINT_INFO("ttc7 0x0302 open cursor request\n");
            if (__check_sess_params_long_ignored(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_push_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OOPEN);
            if (ora_ttc7_oopen_unmarshal_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OCLOSE:           // ttc7 执行statement时关闭cursor请求
            ORA_PRINT_INFO("ttc7 0x0308 close cursor request\n");
            if (__check_sess_params_ttc7_simple(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_push_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OCLOSE7);
            if (ora_ttc7_oclose_unmarshal_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OCCA:
        case ORA_FUN_CODE_OCANA:
            ORA_PRINT_INFO("ttc8 0x03%02x close request\n", s_fun_code);
            if (__check_sess_params_long_ignored(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OCLOSE8);
            if (ora_ttc8_oall8_close_unpack(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OLOGOFF:
            ORA_PRINT_INFO("0x0309 logoff request\n");
            if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_LOGOFF);
            if (ora_ttc8_doOLOGOFF_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OROLLBACK:
            ORA_PRINT_INFO("0x030F rollback request\n");
            if (__check_sess_params_ttc7_simple(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_ROLLBACK);
            if (ora_ttc8_doOROLLBACK_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OCOMMIT:
            ORA_PRINT_INFO("0x030E commit request\n");
            if (__check_sess_params_ttc7_simple(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_COMMIT);
            if (ora_ttc8_doOCOMMIT_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OVERSION:         // OVersion请求
            ORA_PRINT_INFO("0x033B OVersion request\n");
            APM_ORA_SET_PHASE_P_OVERSION_REQ(p_st_sess->ull_bits_phase_progress);
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OVERSION);
            if (ora_tti_oversion_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OTXEN:            // OTXEN请求
            ORA_PRINT_INFO("0x0368 OTXEN request\n");
            ora_reset_sess_phase(p_st_sess->arr_sess_phase);
            bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
            break;

        case ORA_FUN_CODE_OCANCEL:          // ttc7 closeQuery请求
            ORA_PRINT_INFO("0x0314 closeQuery request\n");
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_CANCEL7);
            bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
            break;

        case ORA_FUN_CODE_ODNY:             // ttc7 查询metadata
            ORA_PRINT_INFO("0x0362 ODNY request\n");
            if (__check_sess_params_ttc7(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_push_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_ODNY);
            if (ora_ttc7_odscrarr_unmarshal_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        case ORA_FUN_CODE_OLOBOPS:          // ttc8 操作BLOB数据
            ORA_PRINT_INFO("0x0360 LOB request\n");
            if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                goto error;
            ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_LOB);
            if (ora_ttc8_tti_lob_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                goto error;
            break;

        default:
            ORA_PRINT_WARN("Don't know fun code:[0x03%.2x][%d]\n", s_fun_code, s_fun_code);
            ora_reset_sess_phase(p_st_sess->arr_sess_phase);
            bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
            break;
    }

    return i_this_func_ret;
error:
    return APM_L7_ANALYZE_FAIL;
}

/*******************************************************************************
*  FUNC     :  分析request data包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc_proto_analyze_req(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet
                            , Frhash_header *p_st_hash_report)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    Ora_rpc_recv *p_st_ora_rpc_recv = NULL;
    int i_this_func_ret = APM_L7_ANALYZE_SET_REQ(APM_L7_ANALYZE_SUCC);
    Ora_sess_phase arr_tmp_sess_phase[APM_ORA_SESS_PHASE_MAX];
    ora_reset_sess_phase(arr_tmp_sess_phase);

    short s_ttc_code = 0;                                 // ttc code
    short s_fun_code = 0;                                 // fun code

    ora_copy_sess_phase(p_st_sess->arr_sess_phase, arr_tmp_sess_phase);

    ora_clear_ttc7_new_stmt(p_st_conn);

    bytebuff_setPosition(p_st_ora_packet->p_st_packet, APM_ORA_PKT_HEADER_LEN + APM_ORA_DATA_FLAG_LEN);      // 跳过包头和dataflag

    while (1)
    {
        if (bytebuff_remaining(p_st_ora_packet->p_st_packet) == 0) // 已解析完整个数据包
            goto success;

        // 获取 ttc code
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_ttc_code) != FR_SUCC)
            goto error;

        switch (s_ttc_code)
        {
            case APM_TTC_CODE_TTIPRO:           // pro请求 这里不做实际的解析
                ORA_PRINT_INFO("pro request\n");
                ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_PRO);
                APM_ORA_SET_PHASE_P_PRO_REQ(p_st_sess->ull_bits_phase_progress);
                goto success;

            case APM_TTC_CODE_TTIDTY:           // dty请求
                ORA_PRINT_INFO("dty request\n");
                ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_DTY);
                APM_ORA_SET_PHASE_P_DTY_REQ(p_st_sess->ull_bits_phase_progress);
                if (ora_tti_dty_unpack_req(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                goto success;

            case APM_TTC_CODE_TTIPFN:
                if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_fun_code) == FR_FAIL)
                    goto error;
                if (s_fun_code == ORA_FUN_CODE_OCCA || s_fun_code == ORA_FUN_CODE_OCANA) // ttc8 close请求
                {
                    ORA_PRINT_INFO("ttc8 0x11%02x close request\n", s_fun_code);
                    if (__check_sess_params_long_ignored(p_st_session, p_st_sess) != FR_SUCC)
                        goto error;
                    ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OCLOSE8);
                    if (ora_ttc8_oall8_close_unpack(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) != FR_SUCC)
                        goto error;
                }
                else if (s_fun_code == ORA_FUN_CODE_O80SES)
                {
                    ORA_PRINT_INFO("ttc8 0x116B doO80SES request\n");
                    if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                        goto error;
                    ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_O80SES);
                    if (ora_ttc8_oall8_oses_unpack(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                        goto error;
                }
                else if (s_fun_code == ORA_FUN_CODE_OLOBOPS)    // ttc8 操作BLOB数据
                {
                    ORA_PRINT_INFO("0x1160 LOB request\n");
                    if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                        goto error;
                    ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_LOB);
                    if (ora_ttc8_tti_lob_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                        goto error;
                }
                else
                    goto success;
                break;

            case APM_TTC_CODE_TTIRXD:
                ORA_PRINT_INFO("0x07 RXD request\n");
                if (p_st_sess->c_ttc_api_version == 7)
                    ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL7);
                else if (p_st_sess->c_ttc_api_version == 8)
                    ora_set_last_sess_phase(p_st_sess->arr_sess_phase, APM_ORA_SESS_PHASE_OALL8);
                bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
                break;

            case APM_TTC_CODE_TTIFUN:
                if (__ora_tti_fun_analyze_req(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) == APM_L7_ANALYZE_FAIL)
                    goto error;
                break;

            default:
                goto success;
        }
    }

success:
    ora_free((void **) &p_st_ora_rpc_recv);
    return i_this_func_ret;
error:
    if (ora_packet_is_in_fragment(p_st_ora_packet))
        ora_copy_sess_phase(arr_tmp_sess_phase, p_st_sess->arr_sess_phase);
    ora_free((void **) &p_st_ora_rpc_recv);
    return APM_L7_ANALYZE_FAIL;
}

/*******************************************************************************
*  FUNC     :  分析response data包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc_proto_analyze_resp(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet
                            , Frhash_header *p_st_hash_report
                            , Apm_packet *p_st_analyze_in)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_resp_ora *p_st_resp = p_st_session_private->p_st_resp;
    Ora_sess_phase em_curr_sess_phase;
    Ora_rpc_recv *p_st_ora_rpc_recv = NULL;
    Frreport_data *p_st_report_data = NULL;
    char arr_info[64] = {'\0'};
    int i_this_func_ret = APM_L7_ANALYZE_SET_RESP(APM_L7_ANALYZE_SUCC);
    int i_analyze_start_pos = 0;
    Ora_sess_phase arr_tmp_sess_phase[APM_ORA_SESS_PHASE_MAX];
    ora_reset_sess_phase(arr_tmp_sess_phase);

    bytebuff_setPosition(p_st_ora_packet->p_st_packet, APM_ORA_PKT_HEADER_LEN + APM_ORA_DATA_FLAG_LEN);      // 跳过包头和dataflag

    ora_report_closed_stmt(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report);

    while ((em_curr_sess_phase = ora_pop_sess_phase(p_st_sess->arr_sess_phase)) != APM_ORA_SESS_PHASE_INIT)
    {
        ora_push_sess_phase(arr_tmp_sess_phase, em_curr_sess_phase);
        switch (em_curr_sess_phase)
        {
            case APM_ORA_SESS_PHASE_PRO:            // pro响应
                ORA_PRINT_INFO("pro response\n");
                APM_ORA_SET_PHASE_P_PRO_RESP(p_st_sess->ull_bits_phase_progress);
                if (ora_tti_pro_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_DTY:            // dty响应
                ORA_PRINT_INFO("dty response\n");
                APM_ORA_SET_PHASE_P_DTY_RESP(p_st_sess->ull_bits_phase_progress);
                if (ora_tti_dty_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_LOG1:           // ttc7 log1响应
                ORA_PRINT_INFO("ttc7 log1 response\n");
                APM_ORA_SET_PHASE_P_LOG1_RESP(p_st_sess->ull_bits_phase_progress);
                if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_logon1_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;

                if (p_st_resp->l_response_code != 0)
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login reject", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login reject");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON_REJECT, arr_info, &(p_st_ora_packet->st_timestamp_last));
                }

                if (frreport_send(g_p_apm_context, &p_st_report_data) == FR_SUCC)
                    ORA_PRINT_WARN("frreport_send success\n");
                else
                    ORA_PRINT_WARN("frreport_send fail\n");

                i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
                break;

            case APM_ORA_SESS_PHASE_LOG2:           // ttc7 log2响应
                ORA_PRINT_INFO("ttc7 log2 response\n");
                APM_ORA_SET_PHASE_P_LOG2_RESP(p_st_sess->ull_bits_phase_progress);
                if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_logon2_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;

                if (p_st_resp->l_response_code != 0)
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login reject", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login reject");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON_REJECT, arr_info, &(p_st_ora_packet->st_timestamp_last));
                }
                else
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON, arr_info, &(p_st_ora_packet->st_timestamp_last));

                    p_st_sess->st_logined_timestamp.tv_sec = p_st_ora_packet->st_timestamp_last.tv_sec;
                    p_st_sess->st_logined_timestamp.tv_usec = p_st_ora_packet->st_timestamp_last.tv_usec;
                }

                if (frreport_send(g_p_apm_context, &p_st_report_data) == FR_SUCC)
                    ORA_PRINT_WARN("frreport_send success\n");
                else
                    ORA_PRINT_WARN("frreport_send fail\n");

                i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
                break;

            case APM_ORA_SESS_PHASE_OSESSKEY:        // ttc8 log1响应
                ORA_PRINT_INFO("ttc8 log1 response\n");
                APM_ORA_SET_PHASE_P_LOG1_RESP(p_st_sess->ull_bits_phase_progress);
                if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_ttc8_logon_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_LOGON, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);

                if (p_st_resp->l_response_code != 0)
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login reject", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login reject");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON_REJECT, arr_info, &(p_st_ora_packet->st_timestamp_last));

                    if (frreport_send(g_p_apm_context, &p_st_report_data) == FR_SUCC)
                        ORA_PRINT_WARN("frreport_send success\n");
                    else
                        ORA_PRINT_WARN("frreport_send fail\n");
                }

                i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
                break;

            case APM_ORA_SESS_PHASE_OAUTH:           // ttc8 log2响应
                ORA_PRINT_INFO("ttc8 log2 response\n");
                APM_ORA_SET_PHASE_P_LOG2_RESP(p_st_sess->ull_bits_phase_progress);
                if (__check_sess_params_logon(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_ttc8_logon_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_LOGON, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);

                if (p_st_resp->l_response_code != 0)
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login reject", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login reject");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON_REJECT, arr_info, &(p_st_ora_packet->st_timestamp_last));
                }
                else
                {
                    if (p_st_sess->p_username)
                        snprintf(arr_info, sizeof(arr_info), "%s login", p_st_sess->p_username);
                    else
                        snprintf(arr_info, sizeof(arr_info), "login");

                    p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON, arr_info, &(p_st_ora_packet->st_timestamp_last));

                    p_st_sess->st_logined_timestamp.tv_sec = p_st_ora_packet->st_timestamp_last.tv_sec;
                    p_st_sess->st_logined_timestamp.tv_usec = p_st_ora_packet->st_timestamp_last.tv_usec;
                }

                if (frreport_send(g_p_apm_context, &p_st_report_data) == FR_SUCC)
                    ORA_PRINT_WARN("frreport_send success\n");
                else
                    ORA_PRINT_WARN("frreport_send fail\n");

                i_this_func_ret = APM_L7_ANALYZE_SET_LOGIN(i_this_func_ret);
                break;

            case APM_ORA_SESS_PHASE_OOPEN:          // ttc7 执行statement时申请cursor请求时的响应
                ORA_PRINT_INFO("ttc7 open cursor response\n");
                if (__check_sess_params_ttc7_simple(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_oopen_unmarshal_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_OALL7:          // ttc7 执行statement请求时的响应
                ORA_PRINT_INFO("ttc7 0x0347 stmt response\n");
                if (__check_sess_params_ttc7_stmt_resp(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_oall7_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) == FR_FAIL)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_O80SES:
                ORA_PRINT_INFO("ttc8 0x116B doO80SES response\n");
                if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_ttc8_oall8_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_STMT, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);
                break;

            case APM_ORA_SESS_PHASE_OALL8:          // ttc8 执行statement请求时的响应
                ORA_PRINT_INFO("ttc8 0x035E stmt response\n");
                if (__check_sess_params_ttc8_stmt_resp(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if ((p_st_sess->i_use_special_field == FR_NO &&
                        (p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET ||
                        p_st_sess->i_ttc8_stmt_resp_oeraij == APM_ORA_FLAG_UNSET)) ||
                    (p_st_sess->i_use_special_field == FR_YES &&
                        (p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ||
//                         p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET ||
                         p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 == APM_ORA_FLAG_UNSET)))
//                         p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 == APM_ORA_FLAG_UNSET)))
                {
                    i_analyze_start_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
                    if (ora_ttc8_analyze_resp(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_SESS_IS_STMT) != FR_SUCC)
                        return FR_FAIL;
                    bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos);
                }

                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_ttc8_oall8_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_STMT, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);
                break;

            case APM_ORA_SESS_PHASE_OCLOSE7:        // ttc7 0x0308关闭游标的响应
                ORA_PRINT_INFO("ttc7 0x0308 close cursor response\n");
                if (__check_sess_params_ttc7_simple(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_oclose_unmarshal_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report) == FR_FAIL)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_OCLOSE8:        // ttc8 0x1169关闭游标的响应
                ORA_PRINT_INFO("ttc8 0x1169 close cursor response\n");
                if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_ttc8_oall8_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_STMT, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);
                break;

            case APM_ORA_SESS_PHASE_OVERSION:       // OVersion响应
                ORA_PRINT_INFO("0x033B OVersion response\n");
                APM_ORA_SET_PHASE_P_OVERSION_RESP(p_st_sess->ull_bits_phase_progress);
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_tti_oversion_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_OVERSION, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);
                ora_service_list_add(p_st_sess, p_st_analyze_in); // 保存oracle的服务器信息
                break;

            case APM_ORA_SESS_PHASE_ODNY:           // ttc7 查询metadata
                ORA_PRINT_INFO("0x0362 ODNY response\n");
                if (__check_sess_params_ttc7(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                if (ora_ttc7_odscrarr_unmarshal_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_LOB:
                ORA_PRINT_INFO("0x0360 LOB response\n");
                if (__check_sess_params_ttc8(p_st_session, p_st_sess) != FR_SUCC)
                    goto error;
                p_st_ora_rpc_recv = ora_ttc8_rpc_new();
                ora_tti_lob_set_rpc_func(p_st_ora_rpc_recv); // 设置函数指针
                if (ora_ttc8_rpc_unpack_resp(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report, APM_ORA_SESS_IS_LOB, p_st_ora_rpc_recv) == FR_FAIL)
                    goto error;
                ora_free((void **) &p_st_ora_rpc_recv);
                break;

            case APM_ORA_SESS_PHASE_CANCEL7:           // ttc7 closeQuery请求
                ORA_PRINT_INFO("0x0314 closeQuery response\n");
                break;

            case APM_ORA_SESS_PHASE_COMMIT:
                ORA_PRINT_INFO("0x030E commit response\n");
                if (ora_ttc8_doOCOMMIT_unmarshal_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_ROLLBACK:
                ORA_PRINT_INFO("0x030F rollback response\n");
                if (ora_ttc8_doOROLLBACK_unmarshal_resp(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case APM_ORA_SESS_PHASE_LOGOFF:
                ORA_PRINT_INFO("0x0309 logoff response\n");
                if (p_st_sess->p_username)
                    snprintf(arr_info, sizeof(arr_info), "%s logout", p_st_sess->p_username);
                else
                    snprintf(arr_info, sizeof(arr_info), "logout");

                p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGOUT, arr_info, &(p_st_ora_packet->st_timestamp_last));

                if (frreport_send(g_p_apm_context, &p_st_report_data) == FR_SUCC)
                    ORA_PRINT_WARN("frreport_send success\n");
                else
                    ORA_PRINT_WARN("frreport_send fail\n");
                break;

            case APM_ORA_SESS_PHASE_INIT:
                ORA_PRINT_CRIT("SESS_PHASE_INIT\n");
            default:
                ORA_PRINT_CRIT("nothing to do\n");
                goto success;
        }
    }

success:
    ora_free((void **) &p_st_ora_rpc_recv);
    ora_reset_sess_phase(p_st_sess->arr_sess_phase);
    return i_this_func_ret;
error:
    ora_free((void **) &p_st_ora_rpc_recv);

    if (!ora_packet_is_in_fragment(p_st_ora_packet))
        ora_reset_sess_phase(p_st_sess->arr_sess_phase);
    else
        ora_add_sess_phase(arr_tmp_sess_phase, p_st_sess->arr_sess_phase);

    return APM_L7_ANALYZE_FAIL;
}
